package core.api.offer;

import jade.util.Logger;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;

import core.datamodel.AccountData;
import core.datamodel.Constants;
import core.datamodel.Element;
import core.datamodel.ElementValue;
import core.datamodel.Resource;
import core.datamodel.ResourceCounter;

public class OfferVlan {
	private OfferHelper offerModel = null;
	private Logger log = Logger.getJADELogger(this.getClass().getName());
	private boolean flat = false;

	private ArrayList<ElementValue> accountValues = new ArrayList<ElementValue> ();
	private ArrayList<ResourceCounter> accountCounters = new ArrayList<ResourceCounter> ();
	private AccountData account = new AccountData();

	public OfferVlan(boolean flat){
		this.flat = flat;
	}

	public AccountData calculate(Resource resource, Date startTime,	long interval) {
		log.info("Richiesto il calcolo per VirtualMachine offerta a consumo per il timestamp " + startTime);
		offerModel = new OfferHelper( resource, startTime,interval);
		if (flat)
			offerVlanFlat( resource, startTime, interval);
		else
			offerVlanUsage ( resource, startTime, interval);
	
		account.setCounters(accountCounters);
		account.setElementValues(accountValues);

		return account;

	}
	
	private void offerVlanUsage(Resource resource, Date startTime, long interval) {
		
		log.info("Offerta Vlan Usage ");

		Hashtable<String, Float> bandhCosts = new Hashtable<String, Float> ();
		bandhCosts.put("10M", (float) 10);
		bandhCosts.put("20M", (float) 40);
		bandhCosts.put("40M", (float) 100);
		bandhCosts.put("80M", (float) 250);
		
		// get  template value
		String up = null;
		String down = null;
		String internet = null;
		for (Element ele : resource.getElements()){
			if (ele.getName().equals(Constants.VLAN_ELEMENT_DOWN)){
				down = ele.getValue();
			}else if (ele.getName().equals(Constants.VLAN_ELEMENT_UP)){
				up = ele.getValue();
			}else if (ele.getName().equals(Constants.VLAN_ELEMENT_INTERNET)){
				internet = ele.getValue();
			}	
		}
		
		// set total cost
		// total = up + down + internet
		float usageBandwithMonthlyCost = (float) 0.15;
		float upCostMonthly = 0;
		float downCostMonthly = 0;
		float internetCostMonthly = 0;
		
		Float upCost = bandhCosts.get(up);
		Float downCost = bandhCosts.get(down);
		
		if (upCost != null )
			upCostMonthly = upCost.floatValue() ;
		
		if (downCost != null )
			downCostMonthly = downCost.floatValue() ;
		
		if (internet != null && internet.equals("SI")){
			internetCostMonthly= 5;
			usageBandwithMonthlyCost = usageBandwithMonthlyCost +(float)  0.5;
		}
			
		
		if (upCostMonthly + downCostMonthly +internetCostMonthly  > 0){
			
			
			// flat cost
			ResourceCounter dayCounter = offerModel.getDayCounter("CHECK_DATE_VLAN_USAGE", flat);
			if ( dayCounter.isNewCounter() | 
					(( (long)((startTime.getTime() / Constants.MILLIS_DAY) )* Constants.MILLIS_DAY) != 
						dayCounter.getLastUpdate().getTime())  ){
				// new day generate account data

				for (Element ele : resource.getElements()){
					System.out.println(ele.getName());

					if (ele.getName().equals(Constants.RESOURCE_COST_ONERI_FISSI) ){
						accountValues.add( offerModel.getElementValue(ele, dayCounter,upCostMonthly + downCostMonthly  , true));
					} else if (ele.getName().equals(Constants.VLAN_ELEMENT_INTERNET) ){
						accountValues.add( offerModel.getElementValue(ele, dayCounter,internetCostMonthly , true));
					}
				
				} // end for

				dayCounter.setUpdateCounter(true);
				// set normaliza date
				long time = (long) ((long) ( startTime.getTime()/ Constants.MILLIS_DAY)* Constants.MILLIS_DAY );
				dayCounter.setLastUpdate( new Date(time)  );
				accountCounters.add(dayCounter);
			
			} else {
				log.info("No new day and no account date must be generated for resource name="+resource.getResourceName());
			}
			
			
			//usage cost
			// all interval account data
			
			// normalize cost
			
			usageBandwithMonthlyCost = usageBandwithMonthlyCost * (float)100 /(float) 1000 /(float) 8 / (float)(1000) * interval;
			for (Element ele : resource.getElements()){
				
				if (ele.getName().equals(Constants.VLAN_ELEMENT_DOWN) ){
					addAccountElementData(ele, startTime,"VLAN_DOWN_DAY_CHARGE",usageBandwithMonthlyCost, false);
			
				} else if (ele.getName().equals(Constants.VLAN_ELEMENT_UP)){
					addAccountElementData(ele, startTime,"VLAN_UP_DAY_CHARGE",usageBandwithMonthlyCost, false);
				} 
	
			} // end for element
		
		} else {
			log.info("Error no found in Vlan definited profile bandwith .... ");
			
		}

		
		
	}

	private void offerVlanFlat (Resource resource, Date startTime,	long interval ){
		log.info("Offerta Vlan Flat ");

		Hashtable<String, Float> bandhCosts = new Hashtable<String, Float> ();
		bandhCosts.put("10M", (float) 175);
		bandhCosts.put("20M", (float) 400);
		bandhCosts.put("40M", (float) 1000);
		bandhCosts.put("80M", (float) 2500);
		

		
		// get  template value
		String up = null;
		String down = null;
		String internet = null;
		for (Element ele : resource.getElements()){
			if (ele.getName().equals(Constants.VLAN_ELEMENT_DOWN)){
				down = ele.getValue();
			}else if (ele.getName().equals(Constants.VLAN_ELEMENT_UP)){
				up = ele.getValue();
			}else if (ele.getName().equals(Constants.VLAN_ELEMENT_INTERNET)){
				internet = ele.getValue();
			}	
		}
		
		// set total cost
		// total = up + down + internet
		float upCostMonthly = 0;
		float downCostMonthly = 0;
		float internetCostMonthly = 0;
		
		Float upCost = bandhCosts.get(up);
		Float downCost = bandhCosts.get(down);
		
		if (upCost != null )
			upCostMonthly = upCost.floatValue() ;
		
		if (downCost != null )
			downCostMonthly = downCost.floatValue() ;
		
		if (internet != null && internet.equals("SI"))
			internetCostMonthly= 50;
		
		
		if (upCostMonthly + downCostMonthly +internetCostMonthly  > 0){

			ResourceCounter dayCounter = offerModel.getDayCounter("CHECK_DATE_VLAN_FLAT", flat);

			if ( dayCounter.isNewCounter() | 
					(( (long)((startTime.getTime() / Constants.MILLIS_DAY) )* Constants.MILLIS_DAY) != 
						dayCounter.getLastUpdate().getTime())  ){
				// new day generate account data

				for (Element ele : resource.getElements()){
					System.out.println(ele.getName());

					if (ele.getName().equals(Constants.VLAN_ELEMENT_UP) ){
						accountValues.add( offerModel.getElementValue(ele, dayCounter, upCostMonthly, true));
					
					} else if (ele.getName().equals(Constants.VLAN_ELEMENT_DOWN) ){
						accountValues.add( offerModel.getElementValue(ele, dayCounter, downCostMonthly, true));
					
					}else if (ele.getName().equals(Constants.VLAN_ELEMENT_INTERNET) ){
						accountValues.add( offerModel.getElementValue(ele, dayCounter, internetCostMonthly, true));
					}
				} // end for

				dayCounter.setUpdateCounter(true);
				// set normaliza date
				long time = (long) ((long) ( startTime.getTime()/ Constants.MILLIS_DAY)* Constants.MILLIS_DAY );
				dayCounter.setLastUpdate( new Date(time)  );
				accountCounters.add(dayCounter);
			
			} else {
				log.info("No new day and no account date must be generated for resource name="+resource.getResourceName());
			}
		
		} else {
			log.info("Error no found in Vlan definited profile bandwith .... ");
			
		}

	}
	
	// helper method
	private void addAccountElementData( Element element,Date startTime, String counterDayName, float monthlyPrice, boolean flat){
		// calcolo costo per cpu
		if (element.getUsage() != null){
			// ci sono dati di utilizzo allora posso calcolare
			ResourceCounter dayCounter = offerModel.getDayCounter(counterDayName, flat);
			ElementValue eValue = offerModel.getElementValue(element, dayCounter, monthlyPrice, flat);

			dayCounter.setCounterValue(eValue.getTotalDayCharge());
			dayCounter.setUpdateCounter(true);
			dayCounter.setLastUpdate(startTime);

			accountValues.add(eValue);
			accountCounters.add(dayCounter);
			log.info("Add data e counter for element id="+element.getId());

		} else {
			log.info("No usage data for element id="+element.getId());
		}

	}
	
	

}